home *** CD-ROM | disk | FTP | other *** search
- /* LineFile - low level file handler object
- lines are clipped at 255 chars (including trailing \r)
- messages:
- LF_Open Open a new file for reading,
- return (LFile *) arg1
- return name in (char *) arg2
- LF_GetLine Return the line in (LFile *) arg1
- at offset arg3 from the one
- containing the char at arg2 (both long);
- line returned in arg4 (char *), linestart
- in arg5 (long *)
- LF_Close Close the file given by (LFile *) arg1
- Call this if you ever want to open it again!
-
- needs the external routine GenError(str1,str2,str3,str4); whose
- arguments are Pascal strings
- */
-
- #include <Quickdraw.h>
- #include <MemoryMgr.h>
- #include <StdFilePkg.h>
- #include <FileMgr.h>
- #include "LineFile.h"
-
- #define NULL 0L
- #define EOF -1L
-
- #define MaxLength 255
- #define DlglocV 70
- #define DlglocH 82
-
- void doOpen();
- void doGetLine();
- void doClose();
-
- void Pstrcpy( s1, s2 )
- unsigned char *s1, *s2;
- {
- register unsigned char * p1 = s1, * p2 = s2;
- register int i;
-
- for ( i = *p2; i >= 0; --i, ++p1, ++p2 )
- *p1 = *p2;
- }
-
- void LineFile( message, arg1, arg2, arg3, arg4, arg5 )
- int message;
- LFile *arg1;
- long arg2, arg3, arg4, arg5;
- {
- switch ( message ) {
- case LF_Open:
- doOpen( arg1, arg2 ); break;
-
- case LF_GetLine:
- doGetLine( arg1, arg2, arg3, arg4, arg5 ); break;
-
- case LF_Close:
- doClose( arg1 ); break;
- }
- }
-
- static void doOpen( lfile, name )
- register LFile *lfile;
- char *name;
- {
- SFReply reply;
- Point where;
- int err;
- char errstr[256];
-
- where.v = DlglocV;
- where.h = DlglocH;
-
- SFGetFile( where, "", NULL, 1, "TEXT", NULL, &reply );
-
- if ( reply.good ) {
- if ( ( err = FSOpen( reply.fName, reply.vRefNum, &lfile->refnum ) )
- != noErr ) {
- NumToString( (long) err, errstr );
- GenError( "\pCould not open ", reply.fName,
- "\p, error ", errstr );
- lfile->size = 0;
- return;
- }
-
- GetEOF( lfile->refnum, &lfile->size );
- lfile->buf = NewHandle( L_BUFSIZE );
- lfile->count = lfile->pos = 0;
- lfile->start = 0L;
-
- Pstrcpy( name, reply.fName );
- }
-
- else
- lfile->size = 0;
-
- }
-
- int L_backc( f ) /* read char just before mark, back up */
- register LFile *f;
- {
- long p, num_read = L_BUFSIZE;
-
- if ( f->pos > 0 )
- return (*f->buf)[ --f->pos ];
-
- if ( f->start == 0L )
- return EOF;
-
- p = f->start;
- f->start -= L_BUFSIZE;
- if ( f->start < 0L ) f->start = 0L;
-
- SetFPos( f->refnum, fsFromStart, f->start );
- HLock( f->buf );
- FSRead( f->refnum, &num_read, *f->buf );
- HUnlock( f->buf );
-
- f->count = num_read;
- f->pos = p - f->start;
- if ( f->pos > num_read )
- f->pos = num_read;
-
- if ( num_read == 0L )
- return EOF;
- else
- return (*f->buf)[ --f->pos ];
- }
-
- int L_getc( f )
- register LFile *f;
- {
- long num_read = L_BUFSIZE;
-
- if ( f->pos < f->count )
- return (*f->buf)[ f->pos++ ];
-
- f->start += f->count;
- SetFPos( f->refnum, fsFromStart, f->start );
- HLock( f->buf );
- FSRead( f->refnum, &num_read, *f->buf );
- HUnlock( f->buf );
-
- f->count = num_read;
- f->pos = 0;
-
- if ( num_read == 0 )
- return EOF;
- else
- return (*f->buf)[ f->pos++ ];
- }
-
- void L_seek( f, charno )
- register LFile *f;
- long charno;
- {
- f->start = charno;
- f->count = f->pos = 0;
- }
-
- int back_line( f )
- LFile *f;
- {
- register int c;
-
- while ( ( c = L_backc( f ) ) != EOF &&
- c != '\r' ) ;
-
- return c;
- }
-
- int forward_line( f )
- LFile *f;
- {
- register int c;
-
- while ( ( c = L_getc( f ) ) != EOF && c != '\r' ) ;
-
- return c;
- }
-
- static void get_line( f, linestart, newline )
- register LFile *f;
- long *linestart;
- register char newline[];
- {
- register int c, i;
-
- *linestart = f->start + f->pos;
-
- for ( i = 0, c = L_getc( f );
- i < MaxLength-1 && c != EOF && c != '\r';
- ++i, c = L_getc( f ) )
- newline[ i ] = c;
-
- newline[ i++ ] = '\r';
- newline[ i ] = '\0';
- }
-
- static void read_this_line( f, linestart, newline )
- LFile *f;
- long *linestart;
- char newline[];
- {
- if ( back_line( f ) != EOF ) L_getc( f );
- get_line( f, linestart, newline );
- }
-
- static void doGetLine( lfile, charno, offset, line, linestart )
- register LFile *lfile;
- register long charno, offset;
- long *linestart;
- char line[];
- {
- register int i;
-
- if ( charno > lfile->size || lfile->size <= 0 ) {
- line[ 0 ] = '\0';
- return;
- }
-
- L_seek( lfile, charno );
-
- if ( offset > 0 )
- for ( i = 0; i < offset; ++i )
- if ( forward_line( lfile ) == EOF ) {
- line[ 0 ] = '\0';
- return;
- }
-
- if ( offset < 0 )
- for ( i = 0; i > offset; --i )
- if ( back_line( lfile ) == EOF ) {
- line[ 0 ] = '\0';
- return;
- }
-
- read_this_line( lfile, linestart, line );
- }
-
- static void doClose( lfile )
- LFile *lfile;
- {
- DisposHandle( lfile->buf );
- FSClose( lfile->refnum );
- }
-